package com.xiaoye.qbdatahandle.util;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.SkipOperation;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.ObjectUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MongoUtil {

    public static LocalDateTime getModalTime(LocalDateTime localDateTime) {
        return localDateTime.plusHours(8);
    }

    public static LocalDateTime getModalCurrentTime() {
        return LocalDateTime.now().plusHours(8);
    }

    public static void modalQuery(Query query, String... columns) {
        if (null != columns && columns.length > 0) {
            query.fields().include(columns);
        }
    }

    public static Sort getModalSort(Boolean isAsc, String... orderKeys) {
        if (null != orderKeys && orderKeys.length > 0) {
            List<Sort.Order> list = new ArrayList<>();
            for (String key : orderKeys) {
                if (StringUtils.isNotBlank(key)) {
                    Sort.Order order;
                    if (isAsc) {
                        order = Sort.Order.asc(key);
                    } else {
                        order = Sort.Order.desc(key);
                    }
                    list.add(order);
                }
            }
            return Sort.by(list);

        }
        return null;
    }

    public static SkipOperation getSkip(Integer pn, Integer pageSize) {
        if (pn == 0) {
            pn = 1;
        }

        long skip = (pn - 1) * pageSize;
        return Aggregation.skip(skip);

    }

    public static Update getModalUpdate(Object fieldObject, Field... fields) {

        Update update = new Update();
        boolean shouldUpdate = false;
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Annotation mongoField = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
                Annotation mongoId = field.getAnnotation(org.springframework.data.mongodb.core.mapping.MongoId.class);
                Object fieldValue = field.get(fieldObject);

                if (null != mongoField && null != fieldValue && mongoId == null) {
                    // if(mongoId != null) {
                    // update.set("_id", fieldValue);
                    // }else {
                    update.set(field.getName(), fieldValue);
                    if (!shouldUpdate) {
                        shouldUpdate = true;
                        // }
                    }
                }
            }
            if (shouldUpdate) {
                return update;
            }
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Update getModalSetOnInsert(Object fieldObject, Field... fields) {

        Update update = new Update();
        boolean shouldUpdate = false;
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Annotation mongoField = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
                Annotation mongoId = field.getAnnotation(org.springframework.data.mongodb.core.mapping.MongoId.class);
                Object fieldValue = field.get(fieldObject);

                if (null != mongoField && null != fieldValue && mongoId == null) {
                    update.setOnInsert(field.getName(), fieldValue);
                    if (!shouldUpdate) {
                        shouldUpdate = true;
                    }
                }
            }
            if (shouldUpdate) {
                return update;
            }
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void modalInsertUpdate(Update update) {

        LocalDateTime now = getModalCurrentTime();
        update.set("create_time", now);
        update.set("update_time", now);
        update.set("is_del", -1);
    }

    public static void modalUpdate(Update update) {
        if (null != update) {
            update.set("update_time", getModalCurrentTime());
        }
    }

    /**
     * mongo的pn 是从 0开始的 前端从 1开始
     *
     * @param pn
     * @return
     */
    public static Integer getModalPn(Integer pn) {
        if (null == pn) {
            return 0;
        }

        if (pn > 0) {
            return pn - 1;
        }

        return pn;
    }

    public static String getLike(String value) {
        return ".*" + value + ".*";
    }

    /**
     * mongo的pn 是从 0开始的 前端从 1开始
     *
     * @param pn
     * @return
     */
    public static <T> IPage<T> getModalIPage(Integer pn, Integer pageSize, long total, List<T> resultList) {
        IPage<T> page = new Page<>();
        page.setCurrent(++pn);
        page.setSize(pageSize);
        page.setTotal(total);
        page.setRecords(resultList);
        return page;
    }

    public static void modalUpdateMap(Map<String, Object> dataMap, Field[] fields, Object data) {
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            field.setAccessible(true);
            Object val = new Object();
            try {
                val = field.get(data);
            } catch (Exception e) {
                e.printStackTrace();
            }

            String name = field.getName();
            if (!ObjectUtils.isEmpty(val) && !name.equals("id") && !name.equals("indexName")
                && !name.equals("indexType")) {
                dataMap.put(name, val);
            }
        }
    }

}
